//
//  SCViewController.swift
//  bluetooth
//
//  Created by Evan on 2020/9/14.
//  Copyright © 2020 Evan. All rights reserved.
//

import Foundation
import UIKit
import CoreBluetooth
import CoreLocation

class SCViewController: UIViewController,CBPeripheralDelegate {
    
    enum serviceType:Int {
        case info = 0
        case status
        case data
    }
    
    var stype:serviceType = .info
    var peripheral:CBPeripheral?
    
    /// 定位获取的地址
    var curlocation:CLLocation?
    /// 设备序列号地址
    var deviceNo:String?
    /// 16进制蓝牙返回值
    var str16:String?
    
    var labelDes:UILabel!
    
    let locationManager:CLLocationManager = CLLocationManager()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        if #available(iOS 13.0, *) {
            self.view.backgroundColor = .systemBackground
        } else {
            // Fallback on earlier versions
        }
        
        labelDes = UILabel(frame: CGRect(x: 0, y: 60, width: UIScreen.main.bounds.width, height: 100))
        labelDes.lineBreakMode = .byWordWrapping
        self.view.addSubview(labelDes)
        
        let btnNo = UIButton(frame: CGRect(x: 20, y: labelDes.frame.maxY + 20, width: UIScreen.main.bounds.width - 40, height: 40))
        self.view.addSubview(btnNo)
        btnNo.titleLabel?.textAlignment = .center
        btnNo.setTitle("获取设备序列号", for: .normal)
        btnNo.addTarget(self, action: #selector(btnNoClick), for: .touchUpInside)
        
        let btnStart = UIButton(frame: CGRect(x: 20, y: btnNo.frame.maxY + 20, width: UIScreen.main.bounds.width - 40, height: 40))
        self.view.addSubview(btnStart)
        btnStart.titleLabel?.textAlignment = .center
        btnStart.setTitle("发起检测申请", for: .normal)
        btnStart.addTarget(self, action: #selector(btnStartClick), for: .touchUpInside)
        
        let btnLocation = UIButton(frame: CGRect(x: 20, y: btnStart.frame.maxY + 20, width: UIScreen.main.bounds.width - 40, height: 40))
        self.view.addSubview(btnLocation)
        btnLocation.titleLabel?.textAlignment = .center
        btnLocation.setTitle("获取定位地址", for: .normal)
        btnLocation.addTarget(self, action: #selector(btnLocationClick), for: .touchUpInside)
        
        let btnGetValue = UIButton(frame: CGRect(x: 20, y: btnLocation.frame.maxY + 20, width: UIScreen.main.bounds.width - 40, height: 40))
        self.view.addSubview(btnGetValue)
        btnGetValue.titleLabel?.textAlignment = .center
        btnGetValue.setTitle("请求接口详细测试结果", for: .normal)
        btnGetValue.addTarget(self, action: #selector(btnGetValueClick), for: .touchUpInside)
        
        //设置定位服务管理器代理
        locationManager.delegate = self
        //设置定位进度
        locationManager.desiredAccuracy = kCLLocationAccuracyBest //最佳定位
        //更新距离
        locationManager.distanceFilter = 100
        locationManager.requestAlwaysAuthorization()
        locationManager.requestWhenInUseAuthorization()
        
        self.peripheral?.delegate = self
    }
    
    /// 数据服务
    private let serviceData = "BA44B63A-1A21-435A-B75C-AA69A2974352"
    /// 获取蓝牙结果值
    private let serviceDataValue = "A0D64EBA-AD9C-44EA-9E8B-9BBA41B74380"
    /// 状态服务
    private let serviceStatus = "A8F93CCB-B9D6-4746-89FA-C2CC0804FC66"
    /// 开始检测
    private let serviceStatusStart = "10175B2A-AA06-4200-B68C-A28AC752F30F"
    /// 信息服务
    private let serviceInfo = "0000180A-0000-1000-8000-00805F9B34FB"
    
    // 设备序列号
    private let infoNo = "00002A25-0000-1000-8000-00805F9B34FB"
    
    /// 获取设备序列号
    /// - Parameter sender: <#sender description#>
    @objc func btnNoClick(_ sender: Any) {
        stype = .info
        self.peripheral?.discoverServices([CBUUID(string: serviceInfo)])
    }
    
    @objc func btnStartClick(_ sender:Any){
        stype = .status
        self.peripheral?.discoverServices([CBUUID(string: serviceStatus)])
    }
    
    @objc func btnGetValueClick(_ sender:UIButton){

        guard let no = self.deviceNo else {
            self.labelDes.text = "请先获取设备序列号"
            return
        }
        
        guard let s16 = str16 else {
            self.labelDes.text = "请先获取上面步骤功能获取到 16进制蓝牙返回值"
            return
        }
        
        var semaphore = DispatchSemaphore (value: 0)

        var request = URLRequest(url: URL(string: "http://47.107.174.66:8090/api/v1/calculate?ic=&cn=-1&x=\(s16)&sn=\(no)")!,timeoutInterval: Double.infinity)
        request.addValue("9834897289", forHTTPHeaderField: "Green-Appid")

        request.httpMethod = "GET"

        let task = URLSession.shared.dataTask(with: request) { data, response, error in
          guard let data = data else {
            print(String(describing: error))
            return
          }
            DispatchQueue.main.async {

                  let s = String(data: data, encoding: .utf8)!
                  self.labelDes.text = s
                print(s)
            }
          semaphore.signal()
        }

        task.resume()
        semaphore.wait()
    }
    
    
    // 发现服务回调
    func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
        print("发现服务回调")
        switch stype {
        case .info:
            /// 查询硬件序列号
                   if let service = peripheral.services?.first(where: { (s) -> Bool in
                       return s.uuid.description == "Device Information"
                   }) {
                       peripheral.discoverCharacteristics([CBUUID(string: infoNo)], for: service)
                   }
            break
        case .status:
            /// 蓝牙发起检测申请
                   if let service = peripheral.services?.first(where: { (s) -> Bool in
                       return s.uuid.description == serviceStatus
                   }) {
                       peripheral.discoverCharacteristics([CBUUID(string: serviceStatusStart)], for: service)
                   }
                   
            break
        case .data:

            /// 获取蓝牙检测结果
            if let service = peripheral.services?.first(where: { (s) -> Bool in
                return s.uuid.description == serviceData
            }) {
                peripheral.discoverCharacteristics([CBUUID(string: serviceDataValue)], for: service)
            }
            break
        }
       
        
       
    }
    
    //发现特征回调
    func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
        print("发现特征回调息didDiscoverCharacteristicsFor")
        
        if let s = service.characteristics?.first(where: { (cb) -> Bool in
            return cb.uuid.description == "Serial Number String"
        }){
            self.peripheral?.readValue(for: s)
        }
        
        if let s = service.characteristics?.first(where: { (cb) -> Bool in
            return cb.uuid.description == serviceStatusStart
        }){
            let data = Data(bytes: [0x01], count: 1)
            self.peripheral?.writeValue(data, for: s, type: .withResponse)
            DispatchQueue.main.asyncAfter(deadline: .now()+4) {
                self.stype = .data
                self.peripheral?.discoverServices([CBUUID(string: self.serviceData)])
            }
        }
        
        if let s = service.characteristics?.first(where: { (cb) -> Bool in
            return cb.uuid.description == serviceDataValue
        }){
            self.peripheral?.readValue(for: s)
        }
        
        
    }
    
    //从蓝牙设备获取返回值
    func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
        /// 获取到查询的值
        if characteristic.uuid.description == "Serial Number String",let d = characteristic.value{
            let s = String(data: d, encoding: .utf8)
            let str = "设备信息序列号：\(s ?? "")"
            print(str)
            self.deviceNo = s
            self.labelDes.text = str
        }else if characteristic.uuid.description == serviceDataValue,let d = characteristic.value{
//            let s = String(data: d, encoding: .utf8)
            
            var ss = ""
            d.forEach { (i) in
                ss += " \(i)"
            }
            let str = "检测结果：\(ss)"
            self.labelDes.text = str
            print(str)
            
            let s16 = d.hexadecimal()
            self.str16 = s16
            print("16进制：\(s16)")
        }
        
        
        //        if let d = characteristic.value {
        //            let s = String(data: d, encoding: .utf8)!
        //            print("发现特征回调息didUpdateValueFor：\(characteristic.uuid)   \(s)")
        //        }
        
    }
    
    
    ///向蓝牙设备发送信息是否成功
    /// - Parameters:
    ///   - peripheral: <#peripheral description#>
    ///   - characteristic: <#characteristic description#>
    ///   - error: <#error description#>
    func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
        print("向蓝牙设备发送信息是否成功：\(error)")
//        let alert = UIAlertController()
//        let ok = UIAlertAction(title: "查询指令发送成功", style: .default) { (ac) in
//            self.peripheral?.discoverServices([CBUUID(string: "BA44B63A-1A21-435A-B75C-AA69A2974352")])
//        }
//        alert.addAction(ok)
//        self.present(alert, animated: true, completion: nil)
        
    }
    
}

extension Data {

    /// Create hexadecimal string representation of `Data` object.
    ///
    /// - returns: `String` representation of this `Data` object.

    func hexadecimal() -> String {
        return map { String(format: "%02x", $0) }
            .joined(separator: "")
    }
}

// 定位
extension SCViewController:CLLocationManagerDelegate{
    
    @objc func btnLocationClick(sender:UIButton){
        
        if CLLocationManager.locationServicesEnabled() {
           
            //发出授权请求
//            locationManager.requestAlwaysAuthorization()
            locationManager.startUpdatingHeading()
            locationManager.startUpdatingLocation()
            print("定位开始")
        }
    }
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        // 获取最新坐标
        curlocation = locations.last
        // 纬度
        let w = curlocation?.coordinate.latitude
        // 经度
        let j = curlocation?.coordinate.longitude
        let s = "定位地址： lat:\(w ??  0)  long:\(j ?? 0)"
        self.labelDes.text = s
        print(s)
    }
    
}
